<template>
  <div>
    <el-card>
      <el-form inline>
        <el-form-item>
          <el-input placeholder="用户名" v-model="paramsState.username"/>
        </el-form-item>
        <!-- icon -->
        <el-form-item>
          <el-button type="primary" icon="el-icon-search" @click="search">查询</el-button>
          <el-button type="default" @click="resetSearch">清空</el-button>
        </el-form-item>
      </el-form>
      <!-- 添加/批量删除 -->
      <div style="margin: 20px 0">
        <el-button type="primary" @click="showAddUser">添 加</el-button>
        <el-button type="danger" @click="revomveUsers" :disabled="this.tableState.selectedIds.length===0" >批量删除</el-button>
      </div>
      <!-- table表格 -->
      <el-table border stripe v-loading="listLoading" :data="tableState.users" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"   />

        <el-table-column type="index" label="序号" width="80" align="center" />

        <el-table-column prop="username" label="用户名" width="150" />
        <el-table-column prop="nickName" label="用户昵称" />
        <el-table-column prop="roleName" label="角色列表" width="200" />
        <el-table-column prop="gmtCreate" label="创建时间" width="180" />
        <el-table-column prop="gmtModified" label="更新时间" width="180" />

        <el-table-column label="操作" width="200" align="center" fixed="right">
          <template slot-scope="scope">
            <el-button type="info" size="mini" title="分配角色" icon="el-icon-user-solid" @click="handleClick(scope.row)"></el-button>
            <el-button type="primary" size="mini" icon="el-icon-edit-outline" title="修改用户" @click=showUpdateUser(scope.$index,scope.row)></el-button>

            <!-- 气泡确认框 -->
            <el-popconfirm
              :title="`确定删除 ${scope.row.username} 吗?`"
              @confirm="removeUser(scope.$index, scope.row)"
            >
              <template #reference>
                <el-button type="danger" style="margin-left: 10px" size="mini" icon="el-icon-delete" title="删除用户" ></el-button>
              </template>
            </el-popconfirm>

          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器 -->
      <el-pagination
        :current-page="paramsState.page"
        :page-size="paramsState.limit"
        :total="tableState.total"
        :page-sizes="[5, 10, 20, 30]"
        style="padding: 20px 0;"
        layout="prev, pager, next, jumper, ->, sizes, total"
        @current-change="handleCurrentChange"
        @size-change="handleSizeChange"
      />

      <!-- 修改/添加用户 -->
      <!-- :title="userState.user?.id ? '修改用户' : '添加用户'" -->
      <el-dialog 
        :title="userState.user.id ? '修改用户' : '添加用户'"
        :visible.sync="dialogVisible"
      >
        <el-form ref="userFormRef" :model="userState.user" :rules="userRules" label-width="120px">
          <el-form-item label="用户名" prop="username">
            <el-input v-model="userState.user.username" />
          </el-form-item>
          <el-form-item label="用户昵称">
            <el-input v-model="userState.user.nickName" />
          </el-form-item>
          <el-form-item
            v-if="!userState.user.id"
            label="用户密码"
            prop="password"
          >
            <el-input v-model="userState.user.password" />
          </el-form-item>
        </el-form>
        

        <div slot="footer" class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button type="primary"  :loading="userState.userLoading" @click="addOrUpdate">确 定</el-button>
        </div>
      </el-dialog>

      <!-- 设置角色 -->
      <el-dialog title="设置角色" :visible.sync="roleState.dialogRoleVisible">
        <el-form  label-width="80px">
          <el-form-item label="用户名" >
            <el-input disabled :value="userState.user.username"></el-input>
          </el-form-item>
          <el-form-item label="角色列表" >
            <el-checkbox 
              :indeterminate="roleState.isIndeterminate" 
              v-model="roleState.checkAll" 
              @change="handleCheckAllChange"
            >全选</el-checkbox>

            <div style="margin: 15px 0;"></div>
            <el-checkbox-group v-model="roleState.userRoleIds" @change="handleCheckedChange">
              <el-checkbox v-for="role in roleState.allRoles" :label="role.id" :key="role.id">{{role.roleName }}</el-checkbox>
            </el-checkbox-group>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button type="primary" @click="assignRole">保存</el-button>
          <el-button @click="resetRoleData">取 消</el-button>
        </div>
      </el-dialog>
    </el-card>
  </div>
</template>

<script>
import user from '@/api/acl/user'
import { Message } from 'element-ui';

export default {
  name: "",
  data() {
    /* 
    自定义密码校验
    */
    const validatePassword = (rule, value, callback) => {
      if (!value) {
        callback('密码必须输入')
      } else if (!this.value || this.value.length < 6) {
        callback('密码不能小于6位')
      } else {
        callback()
      }
    }

    return {
      listLoading: false, //是否显示列表加载的提示
      //分页数据
      paramsState:{
        username: '',
        searchUsername: "",
        page: 1, // 当前页码
        limit: 5, // 每页数量
      },
      tableState: {
        total: 0,
        users: [],
        selectedIds: [],
      },
      //----------------------------------------
      // 用户状态
      dialogVisible: false,
      // 添加/编辑
      userState: {
        userLoading: false,
        user: {
          username: "",
          nickName: "",
          password: "",
        },
      },
      // 用户添加/修改表单的校验规则
      userRules : { 
        username: [
          { required: true, message: '用户名必须输入' },
          { min: 4, message: '用户名不能小于4位' }
        ],
        password: [
          { required: true, validator: validatePassword }
        ]
      },
      
      //-------------------------------

      // 角色状态
      roleState:{
        dialogRoleVisible: false,
        roleLoading: false,
        checkAll: false,
        isIndeterminate: false,
        userRoleIds: [],
        allRoles: []
      },
    };
  },

  mounted() {
    this.getUsers()
  },

  methods: {
    // 列表选中状态发生改变的监听回调
    handleSelectionChange(selection){
      this.tableState.selectedIds = selection.map(item => item.id)
    },
    //批量删除
    revomveUsers(){
      this.$confirm('确定删除吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async() => {
        await user.removeUsers(this.tableState.selectedIds)
        this.$message({
          type: 'success',
          message: '删除成功!',
        });
        //刷新页面
        this.getUsers()
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });          
      });
    },
    //------------------------
    //分配角色
    // 显示指定角色的页面
    handleClick(user){ 
      this.roleState.dialogRoleVisible = true
      // console.log(user.username);
      this.userState.user = user
      this.getRoleHandler()
    },

    // 重置角色用户数据
    resetRoleData(){
      Object.assign(this.roleState, {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false
      })
    },

    //全选
    handleCheckAllChange(value) {
      // console.log(val)  // value 当前勾选状态true/false
      // 如果当前全选, userRoleIds就是所有角色id的数组, 否则是空数组
      this.roleState.userRoleIds = value ? this.roleState.allRoles.map(item => item.id) : []
      // 如果当前不是全选也不全不选时, 肯定为false
      this.roleState.isIndeterminate = false
    },
    
    //选中某一个
    handleCheckedChange(value) {
      // console.log(value);
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.roleState.allRoles.length;
      this.roleState.isIndeterminate = checkedCount > 0 && checkedCount < this.roleState.allRoles.length;
    },

    // 保存的回调
    async assignRole(){
      try {
        const userId = this.userState.user.id
        const roleIds = this.roleState.userRoleIds.join(',')
        this. roleState.roleLoading = true

        await user.assignRoles(userId,roleIds)
        this.roleState.dialogRoleVisible = false
        Message.success('分配角色成功')
        //刷新页面
        this.getUsers()
        this.resetRoleData()
      } catch (error) {
        console.error(error);
        Message.error('分配角色失败')
      }
    },


    // 异步获取用户的角色列表
    async getRoleHandler(){
      try {
        let result = await user.getRoles(this.userState.user.id)
        const {allRolesList, assignRoles} = result.data
        if(result && result.code == 20000){
          // console.log(result);
          this.roleState.allRoles = allRolesList
          this.roleState.userRoleIds = assignRoles.map(item => item.id )
          this.roleState.checkAll = allRolesList.length===assignRoles.length
          this.roleState.isIndeterminate = assignRoles.length>0 && assignRoles.length<allRolesList.length
        }
      } catch (error) {
        console.error(error);
      }
    },

    //----------------------------------------
    // 删除某个用户
    async removeUser(index,row) {
      // console.log(row.id);
      try {
        let result = await user.removeById(row.id)
        if(result && result.code == 20000){
          Message.success('删除成功')
          this.getUsers(this.tableState.users.length===1 ? this.paramsState.page-1 : this.paramsState.page)
        }
      } catch (error) {
        Message.error('删除失败')
        console.error(error)
      }

    },
  
    // 添加弹出dialog
    showAddUser(){
      this.dialogVisible = true
    },

    // 保存或更新用户
    async addOrUpdate() {
      // 发请求
      try {
        // 表单校验
        this.$refs.userFormRef.validate()
        if(this.userState.user.id){//编辑
          await user.update(this.userState.user)
          Message.success('编辑成功!')
        }else{//添加
          await user.add(this.userState.user)
          Message.success('保存成功!')
        }
        //隐藏弹框
        this.dialogVisible = false
        //重置表单
        this.userState.user = {
          username: '',
          nickName: '',
          password: ''
        }
        this.getUsers()
        
      } catch (error) {
        // alert('保存失败')
        Message.error('保存失败')
        console.error(error)
        this.dialogVisible = false
      }
    },

    // 取消
    cancel(){
      this.dialogVisible = false
      this.userState.user = {
        username: '',
        nickName: '',
        password: ''
      }
    },

    // 显示更新用户的界面
    showUpdateUser(index,row) {
      // console.log(row);//当前行
      this.dialogVisible = true
      this.userState.user = {...row}
    },
    // ------------------------------------------------
    // 获取分页列表
    async getUsers (){
      this.listLoading = true
      try {
        // 发送请求
        let result = await user.getPageList(this.paramsState.page,this.paramsState.limit,this.paramsState.username)
        // console.log(result);
        if(result && result.code == 20000){
          this.tableState.users = result.data.items
          this.tableState.total = result.data.total
          this.tableState.selectedIds = []
        }
        this.listLoading = false
      } catch (error) {
        alert('获取分页数据失败')
        console.error(error)
      }
    },
    // 翻页的回调
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`);
      // 组装数据
      this.paramsState.page = val
      //发送请求
      this.getUsers()
    },
    // 每页条数改变的回调
    handleSizeChange(val) {
      console.log(`每页 ${val} 条`);
      // 组装数据
      this.paramsState.limit = val
      //发送请求
      this.getUsers()
    },

    //根据输入进行搜索
    search() {
      // console.log(this.paramsState.username);
      this.paramsState.searchUsername = this.paramsState.username
      // // 获取分页列表的api
      this.getUsers(1)
      //清空
      // this.paramsState.username = ''
    },

    // 重置输入后搜索
    resetSearch() {
      this.paramsState.searchUsername = ''
      this.paramsState.username = ''
      this.getUsers(1)
    }
  }

};
</script>

<style scoped>
</style>